package com.gimi.test_jpa.com.gimi.config;

import com.gimi.test_jpa.com.gimi.entity.login.Account;
import com.gimi.test_jpa.com.gimi.entity.login.Resources;
import com.gimi.test_jpa.com.gimi.entity.login.Role;
import com.gimi.test_jpa.com.gimi.jpa.login.LonginJap;
import com.gimi.test_jpa.com.gimi.jpa.login.ResourceJap;
import com.gimi.test_jpa.com.gimi.jpa.login.RoleJap;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.CrossOrigin;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * 自定义过滤器
 */
@Component
@CrossOrigin
@Slf4j
public class Myfilter extends HttpFilter {
    @Autowired
    private LonginJap longinJap;

    @Autowired
    private RoleJap roleJap;

    @Autowired
    private ResourceJap resourceJap;

    @Override
    public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println(request.getRequestURI() + ">>>>>>>>>>>>>>>>进入了过滤器");

        //验证Token
        String accessToken = request.getHeader("token");
        if (accessToken == null || "".equals(accessToken)) {
            accessToken = request.getParameter("token");
        }
        if (accessToken == null || "".equals(accessToken)) {
            accessToken = request.getHeader("Authorization");
        }
        if (accessToken == null || "".equals(accessToken)) {
            accessToken = request.getHeader("authorization");
        }
        if (accessToken == null || "".equals(accessToken)) {
            accessToken = request.getParameter("Authorization");
        }
        try {
            if (accessToken != null && !accessToken.equals("")) {
                Object token = request.getSession().getAttribute("token");
                if (!accessToken.equals(token)) {
                    throw new RuntimeException("token失效，请重新登录");
                }
                //解析Token
                Claims claims = Jwts.parser().setSigningKey("test_wqy20201211").
                        parseClaimsJws(accessToken).getBody();
                String username = claims.getSubject();
                Object password = claims.get("password");
                log.error("解析Token成功，用户名为:{}，密码为:{}", username, password);

                Account byUsername = longinJap.findByUsername(username);
                if (byUsername == null) {
                    throw new RuntimeException("账号异常！");
                }
                //通过账号信息查到角色信息
                Role role = roleJap.findByAccountId(byUsername.getId());
                if (role == null) {
                    throw new RuntimeException("未获取到该用户的角色信息");
                }

                if (!"admin".equals(role.getName())) {  //admin用户拥有所有权限
                    //通过角色信息查到权限资源信息
                    List<Resources> resources = resourceJap.findByRoleId(role.getId());
                    if (resources == null || resources.size() == 0) {
                        throw new RuntimeException("未获取到该角色的资源信息");
                    }
                    //校验权限
                    Boolean flag = false;
                    for (Resources res : resources) {
                        if (res.getUrl().equals(request.getRequestURI())) {
                            flag = true;
                            break; //一旦校验有权限，就结束当前循环
                        }
                    }
                    if (!flag) {
                        throw new RuntimeException("权限不足无法访问！");
                    }
                }
            } else {
                throw new RuntimeException("token不存在，请重新登录");
            }

            chain.doFilter(request, response);
        }catch (Exception e){
            response.getOutputStream().write(e.getMessage().getBytes());
            return;
        }

    }
}
